#include "Texture.h"

#include <GL/gl.h>
#include <QImage>


namespace
{
    const float fac = 1.f/255.f;
}


Texture::Texture(const std::string& texturePath) :
    textureID(0),
    m_fileName(texturePath)
{

}

void Texture::setFileName(const std::string &fileName)
{
    m_fileName = fileName;
}

Vector3f Texture::getColor(float u, float v)
{
    v = 1.f - v;
    int ui = u * (float)m_image.width();
    int vi = v * (float)m_image.height();
    ui = ui >= m_image.width() ? m_image.width() - 1 : ui;
    vi = vi >= m_image.height() ? m_image.height() - 1 : vi;

    QRgb rgb = m_image.pixel(ui, vi);
    return Vector3f(qRed(rgb) * fac, qGreen(rgb) * fac, qBlue(rgb) * fac);
}

void Texture::load()
{
    if(textureID != 0)
        return;

    m_image = QImage(QString::fromStdString(m_fileName));

    unsigned char *data = new unsigned char[m_image.width()*m_image.height()*3];
    unsigned char *index = data;

    for(int y=m_image.height()-1; y >= 0; --y)
        for(int x=0; x < m_image.width(); ++x)
        {
            QRgb cor = m_image.pixel(x, y);
            *(index++) = qRed(cor);
            *(index++) = qGreen(cor);
            *(index++) = qBlue(cor);
        }

    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_image.width(), m_image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    delete[] data;
}

void Texture::bind()
{
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textureID);
}

void Texture::unbind()
{
    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
}
